package org.locker.device.controller.web;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.locker.common.core.domain.R;
import org.locker.common.core.validate.AddGroup;
import org.locker.common.mybatis.core.page.PageQuery;
import org.locker.common.satoken.utils.LoginHelper;
import org.locker.common.web.core.BaseController;
import org.locker.domain.Order;
import org.locker.domain.bo.OrderBo;
import org.locker.domain.enums.OrderStatusEnum;
import org.locker.domain.vo.OrderVo;
import org.locker.netty.MachineService;
import org.locker.service.IOrderService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * (小程序)订单管理
 *
 * @author lark
 * @date 2023-10-12
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/app/order")
public class WebOrderController extends BaseController {

    private final IOrderService orderService;
    private final MachineService machineService;

    /**
     * 新增订单
     */
    @PostMapping("/add")
    public R<Order> add(@Validated(AddGroup.class) @RequestBody OrderBo bo) {
        return R.ok(orderService.insertByBo(bo));
    }

    /**
     * 查询订单列表
     */
    @GetMapping("/list")
    public R<Page<OrderVo>> list(OrderBo bo, PageQuery pageQuery) {
        pageQuery.setOrderByColumn("create_time");
        pageQuery.setIsAsc("desc");
        bo.setUserId(LoginHelper.getUserId());
        bo.setWxUser(true);
        return R.ok(orderService.queryPageList(bo, pageQuery));
    }


    /**
     * 获取用户有效的订单
     *
     * @return
     */
    @GetMapping("/getActiveOrder/{deviceNo}")
    public R<List<Order>> getActiveOrder(@PathVariable String deviceNo) {
        List<String> statusList = CollUtil.newArrayList();
        statusList.add(OrderStatusEnum.IN_USED.getCode());
        statusList.add(OrderStatusEnum.WAITING_FOR_PAYMENT.getCode());
        List<Order> list = orderService.list(Wrappers.<Order>lambdaQuery().eq(Order::getDeviceNo, deviceNo)
            .in(Order::getOrderStatus, statusList)
            .eq(Order::getUserId, LoginHelper.getUserId()));
        return R.ok(list);
    }

    /**
     * 获取订单详细信息
     *
     * @param orderId 主键
     */
    @GetMapping("/{orderId}")
    public R<OrderVo> getInfo(@NotNull(message = "订单ID不能为空")
                              @PathVariable Long orderId) {
        return R.ok(orderService.queryById(orderId));
    }

    /**
     * desc: 取消订单
     *
     * @param orderId
     * @return
     */
    @GetMapping("/cancel/{orderId}")
    public R<OrderVo> cancel(@NotNull(message = "订单ID不能为空")
                             @PathVariable Long orderId) {
        orderService.cancel(orderId);
        return R.ok();
    }

    /**
     * desc: 结束订单
     *
     * @param orderId
     * @return
     */
    @GetMapping("/close/{orderId}")
    public R<OrderVo> close(@NotNull(message = "订单ID不能为空")
                            @PathVariable Long orderId) {
        //用户+订单号查询,防止被刷
        Order order = orderService.getOne(Wrappers.<Order>lambdaQuery()
            .eq(Order::getOrderId, orderId)
            .eq(Order::getUserId, LoginHelper.getUserId()));
        orderService.close(order, true,false);
        return R.ok();
    }


    /**
     * 开锁
     *
     * @param orderNo
     * @return
     */
    @GetMapping("/open/{orderNo}")
    public R<OrderVo> open(@NotNull(message = "订单号不能为空")
                           @PathVariable String orderNo) {
        //用户+订单号查询,防止被刷
        Order order = orderService.getOne(Wrappers.<Order>lambdaQuery()
            .eq(Order::getOrderNo, orderNo)
            .eq(Order::getOrderStatus, OrderStatusEnum.IN_USED.getCode())
            .eq(Order::getUserId, LoginHelper.getUserId()));
        if (ObjectUtil.isNotNull(order)) {
            machineService.controlOpen(order.getDeviceNo(), order.getDeviceGridId(), order.getOrderNo());
            return R.ok();
        } else {
            return R.fail("订单已失效!");
        }
    }
}
